# 用户管理模块
from BlackWidow.tools import tools
from django import forms
from django.forms.models import model_to_dict
from BlackWidow.models import User
from django.http import JsonResponse
import requests
import json
from django.conf import settings
import time
import re
from django.db import models

def model_to_dict_with_url(model, **kwargs):
    """
    将模型对象转换为字典，并处理特殊字段
    Args:
        model: 模型对象
        **kwargs: 
            is_del_password: 是否删除密码字段，默认为True
    Returns:
        dict: 处理后的字典数据
    """
    model_dict = model_to_dict(model)
    # 格式化时间字段
    model_dict['create_time'] = model.create_time.strftime('%Y-%m-%d %H:%M:%S')
    model_dict['update_time'] = model.update_time.strftime('%Y-%m-%d %H:%M:%S')
    # 安全处理密码字段
    if kwargs.get('is_del_password', True):
        model_dict.pop('password', None)  # 使用None作为默认值，避免KeyError
    return model_dict


class UserManageModelForm(forms.ModelForm):
    """
    用户管理表单类
    用于验证和处理用户数据的表单
    """
    class Meta:
        model = User
        fields = ['user_name', 'account', 'password']

    def clean_password(self):
        """
        密码字段验证
        确保密码符合安全要求
        """
        password = self.cleaned_data.get('password')
        if len(password) < 6:
            raise forms.ValidationError('密码长度不能小于6位')
        if not re.match(r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$', password):
            raise forms.ValidationError('密码必须包含字母和数字')
        return password

    def clean_account(self):
        """
        账号字段验证
        确保账号符合格式要求
        """
        account = self.cleaned_data.get('account')
        if not re.match(r'^[a-zA-Z0-9_]{4,20}$', account):
            raise forms.ValidationError('账号必须是4-20位字母、数字或下划线')
        return account


def wait_user_sync(account, password=None, max_retries=10, delay=1):
    """
    等待用户数据同步到本地数据库
    Args:
        account: 用户账号
        password: 可选，用户密码（用于登录场景）
        max_retries: 最大重试次数
        delay: 每次重试间隔秒数
    Returns:
        dict or None: 用户数据字典或None
    """
    for _ in range(max_retries):
        if password is not None:
            user = User.objects.filter(account=account, password=password).first()
        else:
            user = User.objects.filter(account=account).first()
        if user:
            return model_to_dict_with_url(user, is_del_password=True)
        time.sleep(delay)
    return None


def create_user(request):
    """
    创建用户
    处理用户注册请求，包括本地验证和远程API调用
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        form = UserManageModelForm(request.POST)
        if form.is_valid():
            # 准备注册参数
            account = form.cleaned_data['account']
            password = form.cleaned_data['password']
            
            # 检查账号是否已存在
            if User.objects.filter(account=account).exists():
                return JsonResponse(tools.ReturnData(1, '账号已存在'))

            # 准备API请求参数
            other_params = json.dumps({
                "account": account,
                "password": password
            })
            redirect = tools.get_request_protocol_and_domain(request) + "/api/system/receive_notification/"
            register_data = {
                "account": account,
                "password": password,
                "other_params": other_params,
                "redirect": redirect
            }

            try:
                # 向主服务器注册用户
                response = requests.post(
                    url=settings.BLACKWIDOW_DOMAIN + "/api/platform_user/v2/create/",
                    data=register_data,
                    headers={"Content-Type": "application/x-www-form-urlencoded"},
                    timeout=10  # 设置超时时间
                )

                if response.status_code == 200:
                    response_data = response.json()
                    if response_data.get("code") == 0:
                        # 等待用户数据同步
                        user_data = wait_user_sync(account)
                        if user_data:
                            return JsonResponse(tools.ReturnData(0, '创建成功', data=user_data))
                        return JsonResponse(tools.ReturnData(1, '创建成功但数据同步延迟，请稍后重试'))
                    else:
                        return JsonResponse(tools.ReturnData(1, '创建失败', response_data.get("msg")))
                else:
                    return JsonResponse(tools.ReturnData(1, '创建失败', response.json()))
            except requests.RequestException as e:
                return JsonResponse(tools.ReturnData(1, f'创建失败: 网络请求异常'))
            except Exception as e:
                return JsonResponse(tools.ReturnData(1, f'创建失败: 系统异常'))
        else:
            return JsonResponse(tools.ReturnData(1, '创建失败', tools.get_first_error(form)))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def user_login(request):
    """
    用户登录
    处理用户登录请求，包括本地验证和远程API调用
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        account = request.POST.get('account')
        password = request.POST.get('password')

        # 参数验证
        if not account or not password:
            return JsonResponse(tools.ReturnData(1, '账号或密码参数错误'))

        # 输入验证
        if not re.match(r'^[a-zA-Z0-9_]{4,20}$', account):
            return JsonResponse(tools.ReturnData(1, '账号格式不正确'))

        try:
            # 先尝试本地验证
            user = User.objects.filter(account=account, password=password).first()
            if user:
                data = model_to_dict_with_url(user, is_del_password=True)
                return JsonResponse(tools.ReturnData(0, '登录成功', data=data))

            # 准备API请求参数
            other_params = json.dumps({
                "account": account,
                "password": password
            })
            redirect = tools.get_request_protocol_and_domain(request) + "/api/system/receive_notification/"
            login_data = {
                "account": account,
                "password": password,
                "other_params": other_params,
                "redirect": redirect
            }

            # 向主服务器验证
            response = requests.post(
                url=settings.BLACKWIDOW_DOMAIN + "/api/platform_user/v2/get_platform_user_by_account_and_password/",
                data=login_data,
                headers={"Content-Type": "application/x-www-form-urlencoded"},
                timeout=10  # 设置超时时间
            )

            if response.status_code == 200:
                response_data = response.json()
                if response_data.get("code") == 0:
                    # 等待用户数据同步
                    user_data = wait_user_sync(account, password)
                    if user_data:
                        return JsonResponse(tools.ReturnData(0, '登录成功', data=user_data))
                    return JsonResponse(tools.ReturnData(1, '登录成功但数据同步延迟，请稍后重试'))
                else:
                    return JsonResponse(tools.ReturnData(1, '登录失败', response_data.get("msg")))
            else:
                return JsonResponse(tools.ReturnData(1, '登录失败', response.json()))
        except requests.RequestException as e:
            return JsonResponse(tools.ReturnData(1, '登录失败: 网络请求异常'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, '登录失败: 系统异常'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def get_user_list(request):
    """
    获取用户列表
    支持分页、搜索和多条件查询
    Args:
        request: HTTP请求对象
        Query Parameters:
            page: 页码，默认1
            page_size: 每页数量，默认10
            search: 搜索关键词，支持用户名和账号模糊搜索
            sort_by: 排序字段，支持create_time, update_time, user_name, account
            sort_order: 排序方式，asc或desc，默认desc
            start_time: 开始时间，格式：YYYY-MM-DD HH:MM:SS
            end_time: 结束时间，格式：YYYY-MM-DD HH:MM:SS
    Returns:
        JsonResponse: 包含用户列表和分页信息的JSON响应
    """
    if request.method == 'GET':
        try:
            # 获取查询参数
            page = int(request.GET.get('page', 1))
            page_size = int(request.GET.get('page_size', 10))
            search = request.GET.get('search', '')
            sort_by = request.GET.get('sort_by', 'create_time')
            sort_order = request.GET.get('sort_order', 'desc')
            start_time = request.GET.get('start_time')
            end_time = request.GET.get('end_time')

            # 参数验证
            if page < 1:
                page = 1
            if page_size < 1 or page_size > 100:
                page_size = 10
            if sort_order not in ['asc', 'desc']:
                sort_order = 'desc'
            valid_sort_fields = ['create_time', 'update_time', 'user_name', 'account']
            if sort_by not in valid_sort_fields:
                sort_by = 'create_time'

            # 构建查询
            query = User.objects.all()

            # 搜索条件
            if search:
                query = query.filter(
                    models.Q(user_name__icontains=search) |
                    models.Q(account__icontains=search)
                )

            # 时间范围过滤
            if start_time:
                query = query.filter(create_time__gte=start_time)
            if end_time:
                query = query.filter(create_time__lte=end_time)

            # 排序
            if sort_order == 'desc':
                query = query.order_by(f'-{sort_by}')
            else:
                query = query.order_by(sort_by)

            # 计算总数
            total = query.count()

            # 分页
            start = (page - 1) * page_size
            end = start + page_size
            users = query[start:end]

            # 转换数据
            users_data = [model_to_dict_with_url(user) for user in users]

            # 构建分页信息
            pagination = {
                'total': total,
                'page': page,
                'page_size': page_size,
                'total_pages': (total + page_size - 1) // page_size
            }

            return JsonResponse(tools.ReturnData(0, '获取成功', {
                'users': users_data,
                'pagination': pagination
            }))
        except ValueError as e:
            return JsonResponse(tools.ReturnData(1, f'参数错误: {str(e)}'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'获取失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def update_user_name(request):
    """
    单纯修改用户名（只需提供user_name，用户id从request.user获取）
    Args:
        request: HTTP请求对象
        POST参数: user_name
    Returns:
        JsonResponse: 操作结果
    """
    if request.method != 'POST':
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))
    user_name = request.POST.get('user_name')
    if not user_name:
        return JsonResponse(tools.ReturnData(1, 'user_name参数缺失'))
    if not (2 <= len(user_name) <= 20):
        return JsonResponse(tools.ReturnData(1, '用户名长度需在2-20个字符之间'))
    try:
        user = request.user
        user.user_name = user_name
        user.save()
        return JsonResponse(tools.ReturnData(0, '修改成功', {'user_id': user.user_id, 'user_name': user.user_name}))
    except Exception as e:
        return JsonResponse(tools.ReturnData(1, f'修改失败: {str(e)}'))